package com.qrxl.common;

import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import com.qrxl.enums.HjReturnCode;
import com.qrxl.common.exception.CustomException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.support.MissingServletRequestPartException;

import javax.servlet.http.HttpServletRequest;
import java.beans.PropertyEditorSupport;

/**
 * 公共异常处理
 *
 * @author friday
 */
@ControllerAdvice
public abstract class GlobalExceptionHandler extends PropertyEditorSupport {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 处理自定义的业务异常
     *
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = CustomException.class)
    @ResponseBody
    public JsonResult customExceptionHandler(HttpServletRequest req, CustomException e) {
        logger.error("发生业务异常！原因是：" + e.getMessage());
        if (e.getReturnCode() != null) {
            return JsonResult.genJsonResultWithMsgData(e.getReturnCode(), e.getMessage());
        }
        return JsonResult.genJsonResultWithMsgData(HjReturnCode.ANY_ERROR, e.getMessage());
    }

    /**
     * 的参数类型错误
     *
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = InvalidFormatException.class)
    @ResponseBody
    public JsonResult invalidFormatExceptionHandler(HttpServletRequest req, InvalidFormatException e) {
        logger.error("参数类型错误，请检查：" + e.getMessage());
        return JsonResult.genJsonResultWithMsgData(HjReturnCode.ANY_ERROR, "的参数类型错误");
    }

    /**
     * 参数错误
     *
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = IllegalArgumentException.class)
    @ResponseBody
    public JsonResult illegalArgumentExceptionHandler(HttpServletRequest req, IllegalArgumentException e) {
        logger.error("参数错误，请检查：" + e.getMessage());
        return JsonResult.genJsonResultWithMsgData(HjReturnCode.ANY_ERROR, e.getMessage());
    }

    /**
     * 请求类型异常
     *
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = HttpMediaTypeNotSupportedException.class)
    @ResponseBody
    public JsonResult exceptionHandler(HttpServletRequest req, HttpMediaTypeNotSupportedException e) {
        logger.error("请求类型异常", e);
        return JsonResult.genJsonResultWithMsgData(HjReturnCode.ANY_ERROR, "请使用POST提交json");
    }

    /**
     * 请求类型异常
     *
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = HttpMessageNotReadableException.class)
    @ResponseBody
    public JsonResult exceptionHandler(HttpServletRequest req, HttpMessageNotReadableException e) {
        logger.error("参数格式错误", e);
        return JsonResult.genJsonResultWithMsgData(HjReturnCode.ANY_ERROR, "参数格式错误");
    }

    /**
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
    @ResponseBody
    public JsonResult exceptionHandler(HttpServletRequest req, HttpRequestMethodNotSupportedException e) {
        logger.error("请求方法不正确", e);
        return JsonResult.genJsonResultWithMsgData(HjReturnCode.ANY_ERROR, "请求方法不正确:" + e.getMessage());
    }

    /**
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = MissingServletRequestParameterException.class)
    @ResponseBody
    public JsonResult exceptionHandler(HttpServletRequest req, MissingServletRequestParameterException e) {
        logger.error("请求参数错误", e);
        return JsonResult.genJsonResultWithMsgData(HjReturnCode.ANY_ERROR, "请求参数错误:" + e.getMessage());
    }

    /**
     * 参数校验异常
     *
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseBody
    public JsonResult exceptionHandler(HttpServletRequest req, MethodArgumentNotValidException e) {
        logger.error("参数错误:" + e.getMessage());
        String msg = e.getMessage().split("default message \\[")[2].split("]]")[0];
        return JsonResult.genJsonResultWithMsgData(HjReturnCode.ANY_ERROR, msg);
    }

    /**
     * 参数校验异常
     *
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = BindException.class)
    @ResponseBody
    public JsonResult exceptionHandler(HttpServletRequest req, BindException e) {
        logger.error("参数错误:" + e.getMessage());
        String msg = e.getMessage().split("default message \\[")[2].split("]]")[0];
        return JsonResult.genJsonResultWithMsgData(HjReturnCode.ANY_ERROR, msg);
    }

    /**
     * 唯一约束
     *
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = DuplicateKeyException.class)
    @ResponseBody
    public JsonResult exceptionHandler(HttpServletRequest req, DuplicateKeyException e) {
        logger.error("违反唯一约束", e);
        return JsonResult.genJsonResultWithMsgData(HjReturnCode.ANY_ERROR, "违反唯一约束");
    }

    /**
     * 上传文件错误
     *
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = MissingServletRequestPartException.class)
    @ResponseBody
    public JsonResult exceptionHandler(HttpServletRequest req, MissingServletRequestPartException e) {
        logger.error("请上传文件", e);
        return JsonResult.genJsonResultWithMsgData(HjReturnCode.ANY_ERROR, "请上传文件");
    }

    /**
     * 处理其他异常
     *
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public JsonResult exceptionHandler(HttpServletRequest req, Exception e) {
        logger.error("未知异常", e);
        return JsonResult.genJsonResultWithMsgData(HjReturnCode.ANY_ERROR, "未知错误");
    }
}
